﻿using System;
using Aeon.Configuration;
using Aeon.Emulator.Input;
using Aeon.Emulator.Sound.Blaster;
using Aeon.Emulator.Sound.FM;
using Aeon.Emulator.Sound.Midi;
using Aeon.Emulator.Sound.PCSpeaker;
using Aeon.Emulator.Dos.VirtualFileSystem;

namespace Aeon.Emulator.Launcher
{
    /// <summary>
    /// Contains Aeon launcher environment data.
    /// </summary>
    internal static class LauncherEnvironment
    {
        /// <summary>
        /// The environment's configuration mapper.
        /// </summary>
        private static readonly ConfigurationMapper configMapper = new ConfigurationMapper();

        /// <summary>
        /// Initializes static fields of the LauncherEnvironment class.
        /// </summary>
        static LauncherEnvironment()
        {
            ConfigurationMapper.RegisterDriveConfiguration(typeof(MappedFolderConfiguration));
            ConfigurationMapper.RegisterDriveConfigurationView(typeof(Views.MappedFolderView));
            ConfigurationMapper.RegisterDeviceConfiguration(typeof(FmSoundCardConfiguration));
            ConfigurationMapper.RegisterDeviceConfiguration(typeof(SoundBlasterConfiguration));
            ConfigurationMapper.RegisterDeviceConfiguration(typeof(GeneralMidiConfiguration));
            ConfigurationMapper.RegisterDeviceConfiguration(typeof(InternalSpeakerConfiguration));
            ConfigurationMapper.RegisterDeviceConfiguration(typeof(GamePortConfiguration));
            ConfigurationMapper.RegisterDriveConfiguration(typeof(Aeon.DiskImages.ISOImageConfiguration));
            ConfigurationMapper.RegisterDriveConfigurationView(typeof(Aeon.DiskImages.Views.DiskImageView));
            ConfigurationMapper.RegisterDriveConfiguration(typeof(Aeon.DiskImages.HostCDDriveConfiguration));
            ConfigurationMapper.RegisterDriveConfigurationView(typeof(Aeon.DiskImages.Views.HostDriveView));
        }

        /// <summary>
        /// Gets the environment's configuration mapper.
        /// </summary>
        public static ConfigurationMapper ConfigurationMapper
        {
            get { return configMapper; }
        }

        /// <summary>
        /// Returns a new instance of a quick launch configuration.
        /// </summary>
        /// <param name="hostPath">Host file system path of emulated C drive.</param>
        /// <param name="launchTarget">DOS program to launch. May be null to launch a command line session.</param>
        /// <returns>New quick launch instance with specified targets.</returns>
        public static VirtualMachineConfiguration GetQuickLaunchConfiguration(string hostPath, string launchTarget)
        {
            if(hostPath == null)
                throw new ArgumentNullException("hostPath");

            var config = new VirtualMachineConfiguration { StartupPath = @"C:\", Launch = launchTarget };

            config.Drives.Add(new MountedDrive()
            {
                DriveLetter = DriveLetter.C,
                DriveType = DriveType.Fixed,
                DriveConfiguration = new MappedFolderConfiguration() { HostPath = hostPath }
            });

            foreach(var device in ConfigurationMapper.DeviceConfigurations)
                config.Devices.Add(device.Create());

            return config;
        }
        /// <summary>
        /// Returns a new instance of a quick launch configuration.
        /// </summary>
        /// <param name="hostPath">Host file system path of emulated C drive.</param>
        /// <returns>New quick launch instance with specified target.</returns>
        public static VirtualMachineConfiguration GetQuickLaunchConfiguration(string hostPath)
        {
            return GetQuickLaunchConfiguration(hostPath, null);
        }
    }
}
